package main

import (
	"crypto/md5"
	"flag"
	"fmt"
	"io"
	"os"
)

const bufferSize = 65535

func main() {
	var filepath string
	var tarType string
	var version string
	tarFilepath := "./output.bin"
	flag.StringVar(&tarType, "type", "Host", "firmware type")
	flag.StringVar(&filepath, "path", "./input", "firmware path")
	flag.StringVar(&version, "version", "Y100", "firmware version")
	flag.Parse()
	fmt.Println("[INFO] fileName:", filepath)

	fileInfo, err := os.Stat(filepath)
	if err != nil {
		fmt.Println("[ERROR] path \""+filepath+"\" can't be accessed")
		return
	}
	oriFd, err := os.Open(filepath)
	if err != nil {
		fmt.Println("[ERROR] path \""+filepath+"\" can't be accessed")
		return
	}
	tarFd, err := os.OpenFile(tarFilepath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
	if err != nil {
		fmt.Println("[ERROR] failed to open output file \""+tarFilepath+"\"")
		return
	}

	fileBuf := make([]byte, bufferSize)
	hash := md5.New()

	for ;; {
		count, err := oriFd.Read(fileBuf)
		if err != nil {
			if err == io.EOF {
				break
			}
			fmt.Println("[ERROR] program err \""+err.Error()+"\"")
		}
		hash.Write(fileBuf[:count])
	}
	oriFd.Seek(0, io.SeekStart)

	md5h := hash.Sum(nil)
	
	header := []byte(fmt.Sprintf("FirmwareINFO:{%s,%s,%v,MD5:", tarType, version, fileInfo.Size()))
	header = append(header, md5h...)
	header = append(header, []byte("}END")...)
	fmt.Println("[INFO] " + string(header))
	tarFd.Write(header)
	
	tarFd.Close()
	oriFd.Close()
}